package com.agileai.portal.controller.mobile;

import java.io.StringWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import org.codehaus.jettison.json.JSONArray;
import org.codehaus.jettison.json.JSONObject;

import com.agileai.domain.DataParam;
import com.agileai.domain.DataRow;
import com.agileai.hotweb.annotation.PageAction;
import com.agileai.hotweb.common.BeanFactory;
import com.agileai.hotweb.common.HttpClientHelper;
import com.agileai.hotweb.common.StringTemplateLoader;
import com.agileai.hotweb.controller.core.BaseHandler;
import com.agileai.hotweb.domain.core.Profile;
import com.agileai.hotweb.domain.core.User;
import com.agileai.hotweb.renders.AjaxRenderer;
import com.agileai.hotweb.renders.ViewRenderer;
import com.agileai.portal.bizmoduler.mobile.AngularWidgetManage;
import com.agileai.portal.bizmoduler.mobile.AppModuleConfigManage;
import com.agileai.util.StringUtil;

import freemarker.template.Configuration;
import freemarker.template.ObjectWrapper;
import freemarker.template.Template;

public class MobileDataProviderHandler extends BaseHandler {
	@SuppressWarnings({ "unchecked", "rawtypes" })
	@PageAction
	public ViewRenderer retreiveCtrlFile(DataParam param){
		String responseText = "";
		String menuCode = param.get("menuCode");
		String widgetCode = param.get("widgetCode");
		String controllerFilePath = param.get("filePath");
		
		String cacheKey = menuCode+"!"+ widgetCode;
		synchronized (cacheKey) {
			if (!AngularWidgetManage.ControllerFileContents.containsKey(cacheKey)){
				HttpClientHelper httpClientHelper = new HttpClientHelper();
				String serverName = this.request.getServletContext().getInitParameter("serverName");
				String controllerFileURL = serverName + controllerFilePath;
				String contrllerFileContent = httpClientHelper.retrieveGetReponseText(controllerFileURL);
				
				if (contrllerFileContent != null){
					StringWriter writer = new StringWriter();
					HashMap varRoot = new HashMap();
					varRoot.put("menuCode",menuCode);
					varRoot.put("widgetCode",widgetCode);
					
					this.parseContent(varRoot, contrllerFileContent, writer);
					
					String replacedContent = writer.toString();
					
					AngularWidgetManage.ControllerFileContents.put(cacheKey, replacedContent);					
				}
			}			
		}
		responseText = AngularWidgetManage.ControllerFileContents.get(cacheKey);
		return new AjaxRenderer(responseText);
	}
	
	@SuppressWarnings({ "unchecked", "rawtypes" })
	@PageAction
	public ViewRenderer retrieveAppJs(DataParam param){
		String responseText = "";
		String menuBarCode = param.get("menuBarCode");
		String appJsFilePath = param.get("jsFile");
		HttpClientHelper httpClientHelper = new HttpClientHelper();
		String serverName = this.request.getServletContext().getInitParameter("serverName");
		String appJsFileURL = serverName + appJsFilePath;
		String appJsFileContent = httpClientHelper.retrieveGetReponseText(appJsFileURL);
		if (appJsFileContent != null){
			StringWriter writer = new StringWriter();
			HashMap varRoot = new HashMap();
			varRoot.put("menuBarCode",menuBarCode);
			this.parseContent(varRoot, appJsFileContent, writer);
			responseText = writer.toString();
		}
		return new AjaxRenderer(responseText);
	}
	
	private List<DataRow> getAuthedRecords(List<DataRow> tempRecords){
		List<DataRow> result = new ArrayList<DataRow>();
		Profile profile = this.getProfile();
		if (profile != null){
			User user = (User)profile.getUser();
			for (int i=0;i < tempRecords.size();i++){
				DataRow row = tempRecords.get(i);
				String appModuleId = row.stringValue("AC_ID");
				if (user.containResouce("AppModuleConfig", appModuleId)
						|| "user".equals(user.getUserCode()) || "admin".equals(user.getUserCode())){
					result.add(row);
				}
			}
		}
		return result;
	}
	
	@SuppressWarnings("unchecked")
	public List<AppModule> getAppModuleList(User user){
		List<AppModule> AppModules = new ArrayList<AppModule>();
		try {
			DataParam queryParam = new DataParam("USER_ID",user.getUserId());
			AppModuleConfigManage appModuleConfigManage = (AppModuleConfigManage)BeanFactory.instance().getBean("appModuleConfigManageService");
			DataRow record =  appModuleConfigManage.getUserAppConfig(queryParam);
			String appConfig = record.getString("APP_CONFIG");
			if(StringUtil.isNullOrEmpty(appConfig)){
				DataParam param = new DataParam();
				List<DataRow> tempRecords =  appModuleConfigManage.findRecords(param);
				//权限过滤
				List<DataRow> records = getAuthedRecords(tempRecords);
				//存入到user临时属性
				if(user.getTempProperties().containsKey(user.getUserId()+"AppModule")){
					AppModules = (List<AppModule>)user.getTempProperties().get(user.getUserId()+"AppModule");
				}else{
					for(int i=0;i<records.size();i++){
						DataRow row = records.get(i);
						AppModule appModule = new AppModule();
						appModule.setId(row.getString("AC_ID"));
						appModule.setName(row.getString("AC_NAME"));
						appModule.setCss(row.getString("AC_CSS"));
						appModule.setMethod(row.getString("AC_METHOD"));
						appModule.setVaild(row.getString("AC_VAILD"));
						appModule.setGroup(row.getString("AC_GROUP"));
						appModule.setSort(row.getInt("AC_SORT"));
						AppModules.add(i, appModule);
					}
					user.getTempProperties().put(user.getUserId()+"AppModule",AppModules);
				}
			}else{
				if(user.getTempProperties().containsKey(user.getUserId()+"AppModule")){
					AppModules = (List<AppModule>)user.getTempProperties().get(user.getUserId()+"AppModule");
				}else{
					JSONArray jsonArray =new JSONArray(appConfig);
					for(int i=0;i<jsonArray.length();i++){
						String appModuleId = (String) jsonArray.get(i);
						AppModule appModule = appModuleConfigManage.receiveAppModuleRecord(appModuleId);
						AppModules.add(i, appModule);
					}
					user.getTempProperties().put(user.getUserId()+"AppModule",AppModules);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return AppModules;
	}	

	public List<AppModule> findAllAppModuleList(){
		List<AppModule> AppModules = new ArrayList<AppModule>();
		try {
			AppModuleConfigManage appModuleConfigManage = (AppModuleConfigManage)BeanFactory.instance().getBean("appModuleConfigManageService");
			DataParam param = new DataParam();
			List<DataRow> tempRecords =  appModuleConfigManage.findRecords(param);
			List<DataRow> records = this.getAuthedRecords(tempRecords);
			for(int i=0;i<records.size();i++){
				DataRow row = records.get(i);
				AppModule appModule = new AppModule();
				appModule.setId(row.getString("AC_ID"));
				appModule.setName(row.getString("AC_NAME"));
				appModule.setCss(row.getString("AC_CSS"));
				appModule.setMethod(row.getString("AC_METHOD"));
				appModule.setVaild(row.getString("AC_VAILD"));
				appModule.setGroup(row.getString("AC_GROUP"));
				appModule.setSort(row.getInt("AC_SORT"));
				AppModules.add(i, appModule);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return AppModules;
	}
	
	@PageAction
	public ViewRenderer findAppModuleList(DataParam param){
		String responseText = "";
		try {
			User user = (User) this.getUser();
			List<AppModule> AppModules = this.getAppModuleList(user);
			JSONArray jsonArray = new JSONArray();
			for(int i=0;i<AppModules.size();i++){
				AppModule AppModule = AppModules.get(i);
				JSONObject jsonObject = new JSONObject();
				jsonObject.put("id", AppModule.getId());
				jsonObject.put("text", AppModule.getName());
				jsonArray.put(jsonObject);
			}
			JSONObject jsonObject = new JSONObject();
			jsonObject.put("moduleList", jsonArray);
			responseText = jsonObject.toString();
		} catch (Exception e) {
			log.error(e.getLocalizedMessage(), e);
		}
		return new AjaxRenderer(responseText);
	}
	
	@PageAction
	public ViewRenderer findToChooseAppModuleList(DataParam param){
		String responseText = "";
		try {
			User user = (User) this.getUser();
			List<AppModule> AppModules = this.getAppModuleList(user);
			List<AppModule> AllAppModules = this.findAllAppModuleList();
			for(int i=0;i<AppModules.size();i++){
				AppModule appModule = AppModules.get(i);
				String appModuleId = appModule.getId();
				for(int j=0;j<AllAppModules.size();j++){
					AppModule allAppModule = AllAppModules.get(j);
					String allAppModuleId = allAppModule.getId();
					if(appModuleId.equals(allAppModuleId)){
						AllAppModules.remove(j);
					}
				}
			}
			JSONArray jsonArray = new JSONArray();
			for(int i=0;i<AllAppModules.size();i++){
				AppModule AppModule = AllAppModules.get(i);
				JSONObject jsonObject = new JSONObject();
				jsonObject.put("id", AppModule.getId());
				jsonObject.put("text", AppModule.getName());
				jsonArray.put(jsonObject);
			}
			JSONObject jsonObject = new JSONObject();
			jsonObject.put("toChooseModuleList", jsonArray);
			responseText = jsonObject.toString();
		} catch (Exception e) {
			log.error(e.getLocalizedMessage(), e);
		}
		return new AjaxRenderer(responseText);
	}
	
	@PageAction
	public ViewRenderer mobileSaveAppModule(DataParam param){
		String responseText = FAIL;
		try {
			User user = (User) this.getUser();
			String mark = param.getString("mark");
			String receiveList = this.getInputString();
			AppModuleConfigManage appModuleConfigManage = lookupService(AppModuleConfigManage.class);
			String userCode = user.getUserCode();
			DataParam queryParam = new DataParam("USER_CODE",userCode);
			DataRow record =  appModuleConfigManage.getUserAppConfig(queryParam);
			String appConfig = record.getString("APP_CONFIG");
			JSONArray appArray = new JSONArray();
			if(StringUtil.isNotNullNotEmpty(appConfig)){
				appArray = new JSONArray(appConfig);
			}
			if("sort".equals(mark)){
				appModuleConfigManage.saveAppModuleConfig(receiveList,user.getUserId());
			}else if("selected".equals(mark)){
				JSONArray jsonreceive = new JSONArray(receiveList);
				for(int i=0;i<jsonreceive.length();i++){
					JSONObject jsonObject = jsonreceive.getJSONObject(i);
					String id = jsonObject.getString("id");
					appArray.put(appArray.length(), id);
				}
				String appModuleConfig = appArray.toString();
				appModuleConfigManage.saveAppModuleConfig(appModuleConfig,user.getUserId());
			}else if("delete".equals(mark)){
				String id = param.getString("id");
				ArrayList<String> delList = new ArrayList<String>(); 
				delList.add(id);
				ArrayList<String> list = new ArrayList<String>(); 
				if (appArray != null) { 
					 for (int i=0;i<appArray.length();i++){ 
						 list.add(appArray.get(i).toString());
					 } 
					 list.removeAll(delList);
					 JSONArray jsArray = new JSONArray(list);
					appModuleConfigManage.saveAppModuleConfig(jsArray.toString(),user.getUserId());
				}
			}
			user.getTempProperties().remove(user.getUserId()+"AppModule");
			responseText = SUCCESS;
		} catch (Exception e) {
			log.error(e.getLocalizedMessage(), e);
		}
		return new AjaxRenderer(responseText);
	}
	
	@SuppressWarnings("rawtypes")
	private void parseContent(Map root,String template,StringWriter writer) {
		String encoding = "utf-8";
		try {
        	Configuration cfg = new Configuration();
        	cfg.setTemplateLoader(new StringTemplateLoader(template));  
        	cfg.setEncoding(Locale.getDefault(), encoding);
            cfg.setObjectWrapper(ObjectWrapper.BEANS_WRAPPER);
        	Template temp = cfg.getTemplate("");
        	temp.setEncoding(encoding);
            temp.process(root, writer);
            writer.flush();
		} catch (Exception e) {
			log.error(e.getMessage(), e);
		}
	}
	
	protected static void removeCache(String widgetCode){
		Iterator<String> iter = AngularWidgetManage.ControllerFileContents.keySet().iterator();
		while (iter.hasNext()) {
			String key = (String) iter.next();
			if (key.endsWith("!"+widgetCode)){
				AngularWidgetManage.ControllerFileContents.remove(key);
				AngularWidgetManage.TemplateFileContents.remove(key);
				break;
			}
		}
	}
	
	protected static void removeWidgetCache(String widgetId){
		if (AngularWidgetManage.AngularWidgetCache.containsKey(widgetId)){
			AngularWidgetManage.AngularWidgetCache.remove(widgetId);
		}
	}	
	
	protected static void removeCaches(){
		AngularWidgetManage.ControllerFileContents.clear();
		AngularWidgetManage.TemplateFileContents.clear();
		AngularWidgetManage.AngularWidgetCache.clear();
		AppModuleConfigManage.AppModuleCache.clear();
	}
}